-- By upizpp
-- https://gitee.com/upizpp/json-for-cyf-lua

return (function()
    local json = {}

    json._table_to_string = function(table, indent, level)
        local result = ""
        local fix = ""
        local flag = false
        for index, value in pairs(table) do
            if flag == false then
                if indent == "" then
                    if type(index) == "string" then
                        fix = "{%s}"
                    else
                        fix = "[%s]"
                    end
                else
                    if type(index) == "string" then
                        fix = "{\n%s\n" .. indent:rep(level - 1) .. "}"
                    else
                        fix = "[\n%s\n" .. indent:rep(level - 1) .. "]"
                    end
                end
                flag = true
            end
            if indent == "" then
                if type(index) == "string" then
                    result = result .. "\"" .. index .. "\": " .. json._tostring(value, indent, level) .. ", "
                else
                    result = result .. json._tostring(value, indent, level) .. ", "
                end
            else
                if type(index) == "string" then
                    result = result ..
                            indent:rep(level) .. "\"" .. index .. "\": " .. json._tostring(value, indent, level) .. ",\n"
                else
                    result = result .. indent:rep(level) .. json._tostring(value, indent, level) .. ",\n"
                end
            end
        end
        result = result:sub(1, result:len() - 2)
        return string.format(fix, result)
    end
    json._tostring = function(value, indent, level)
        level = level or 0
        indent = indent or ""
        if type(value) == "table" then
            return json._table_to_string(value, indent, level + 1)
        elseif type(value) == "string" then
            return "\"" .. value .. "\""
        else
            return tostring(value)
        end
    end

    ---@return JsonObject
    ---@param path string # 文件路径
    ---打开一个json文件，并返回一个JSONObject
    function json.open(path)
        ---@class JsonObject
        local _object = {}
        _object.file = Misc.OpenFile(path, "rw")

        ---@param data any
        ---@param indent ?Indent|string
        function _object.save(data, indent)
            _object.file.Write(json.print(data, indent), false)
        end

        ---加载一个json文件
        ---@return any
        function _object.load()
            local lines = _object.file.ReadLines()
            local data = ""
            for i = 1, #lines do
                data = data .. lines[i] .. "\n"
            end
            local lua_data = json.to_lua(data)
            local result = load("return " .. lua_data)()
            return result
        end

        return _object
    end

    ---@return string
    ---@param data any # 要打印的数据
    ---@param indent ?Indent # 缩进
    ---将data以字符串的形式打印出来
    function json.print(data, indent)
        local indent = indent or ""
        local result = json._tostring(data, indent)
        return result
    end

    ---@param content string
    ---@return string
    ---将jsono文本转为lua的表的形式。
    function json.to_lua(content)
        local reg = "\"[^:,]*\"%s*:"
        return ({
            content:gsub(reg, function (match)
                return match:gsub("\"", ""):gsub(":", "=")
            end):gsub("%[", "{"):gsub("%]", "}")
        })[1]
    end

    return json
end)()

---@alias Indent
---| "\\t"
---| "    "
---| "  "
